package task

import (
	"errors"
	"fmt"
	"log"
	"strings"
)

type DbHandler struct {
	flow *FlowTask
}

func NewDbHandler(flow *FlowTask) *DbHandler {
	m := new(DbHandler)
	m.flow = flow
	return m
}

//ExecSql 执行插入语句
func (m *DbHandler) Exec(node *Node) error {
	sql := node.Content["sql"]
	dataSourceId := node.Content["dataSourceId"]
	dyWhere := strings.Split(node.Content["dyWhere"], "\n")
	input := m.flow.BindInput(node.Params)
	db := DBS[dataSourceId]
	if db == nil {
		return errors.New("执行SQL：数据库连接失效！")
	}
	fmt.Println(input)
	if strings.HasPrefix(strings.ToLower(sql), "update") {
		first := strings.Index(strings.ToLower(sql), " set ") + 4
		end := strings.Index(strings.ToLower(sql), " where ")
		where := sql[first:end]
		wheres := strings.Split(where, ",")
		whs := make([]string, 0)
		for _, v := range wheres {
			f := strings.LastIndex(v, ":") + 1
			key := strings.TrimSpace(v[f:])
			val := input[key]

			if val != nil {
				va, ok := val.(string)
				if ok {
					if va != "" {
						whs = append(whs, v)
					}
				} else {
					whs = append(whs, v)
				}
			}
		}
		sql = sql[0:first] + " " + strings.Join(whs, ",") + " " + sql[end:]
	}
	dy := make([]string, 0)
	for _, v := range dyWhere {
		if strings.TrimSpace(v) == "" {
			continue
		}
		f := strings.LastIndex(v, ":") + 1
		key := strings.TrimSpace(v[f:])
		val := input[key]
		if val != nil {
			va, ok := val.(string)
			if ok {
				if va != "" {
					dy = append(dy, v)
				}
			} else {
				dy = append(dy, v)
			}
		}
	}
	if len(dy) != 0 {
		sql += strings.Join(dy, " ")
	}
	fmt.Println(sql)
	_, err := db.NamedExec(sql, input)
	if err != nil {
		log.Println("执行SQL语句失败", sql, err)
		return err
	}
	return nil
}

//ExecQuery 执行查询语句
func (m *DbHandler) Query(node *Node) error {
	sql := node.Content["sql"]
	dataSourceId := node.Content["dataSourceId"]
	success := node.Content["success"]
	dataType := node.Content["dataType"]
	dyWhere := strings.Split(node.Content["dyWhere"], "\n")
	input := m.flow.BindInput(node.Params)
	db := DBS[dataSourceId]
	if db == nil {
		return errors.New("数据库连接失效！")
	}
	dy := make([]string, 0)
	for _, v := range dyWhere {
		if strings.TrimSpace(v) == "" {
			continue
		}
		f := strings.LastIndex(v, ":") + 1
		key := strings.TrimSpace(v[f:])
		val := input[key]
		if val != nil {
			va, ok := val.(string)
			if ok {
				if va != "" {
					dy = append(dy, v)
				}
			} else {
				dy = append(dy, v)
			}
		}
	}
	if len(dy) != 0 {
		sql += strings.Join(dy, " ")
	}
	fmt.Println(sql)
	rows, err := db.NamedQuery(sql, input)
	if err != nil {
		return err
	}
	result := make([]map[string]interface{}, 0)
	for rows.Next() {
		item := make(map[string]interface{}, 0)
		err := rows.MapScan(item)
		if err != nil {
			log.Fatalln(err)
		}
		for k, v := range item {
			item[k] = fmt.Sprintf("%s", v)
		}
		result = append(result, item)
	}

	if success != "" {
		ok, err := m.flow.Expression(success, "", nil, result)
		if !ok && err != nil {
			log.Println("执行SQL结果验证未通过", err)
			return err
		}
	}

	if dataType == "list" {
		m.flow.outList[node.Id] = result
	} else {
		m.flow.out[node.Id] = result[0]
	}
	return err
}
